#include "at_http_register.h"
#include "ML307.h"
#include "t_at.h"
#include "cjson.h"
http_info_t http_info = {
	  .app_lock=0,
	  .productId = 164, // 产品ID (由平台决定)
    .http_url = "",    
    .reg_url_path = "",         
    .body = ""  // 注册内容()由用户生成
};
#define CERT_SIZE (sizeof(tcer) - 1)
const static char tcer[] = 
    "-----BEGIN CERTIFICATE-----\n"
    "MIIEfjCCA2agAwIBAgIQD+Ayq4RNAzEGxQyOE8iwaDANBgkqhkiG9w0BAQsFADBh\n"
    "MQswCQYDVQQGEwJVUzEVMBMGA1UEChMMRGlnaUNlcnQgSW5jMRkwFwYDVQQLExB3\n"
    "d3cuZGlnaWNlcnQuY29tMSAwHgYDVQQDExdEaWdpQ2VydCBHbG9iYWwgUm9vdCBD\n"
    "QTAeFw0yNDAxMTgwMDAwMDBaFw0zMTExMDkyMzU5NTlaMGExCzAJBgNVBAYTAlVT\n"
    "MRUwEwYDVQQKEwxEaWdpQ2VydCBJbmMxGTAXBgNVBAsTEHd3dy5kaWdpY2VydC5j\n"
    "b20xIDAeBgNVBAMTF0RpZ2lDZXJ0IEdsb2JhbCBSb290IEcyMIIBIjANBgkqhkiG\n"
    "9w0BAQEFAAOCAQ8AMIIBCgKCAQEAuzfNNNx7a8myaJCtSnX/RrohCgiN9RlUyfuI\n"
    "2/Ou8jqJkTx65qsGGmvPrC3oXgkkRLpimn7Wo6h+4FR1IAWsULecYxpsMNzaHxmx\n"
    "1x7e/dfgy5SDN67sH0NO3Xss0r0upS/kqbitOtSZpLYl6ZtrAGCSYP9PIUkY92eQ\n"
    "q2EGnI/yuum06ZIya7XzV+hdG82MHauVBJVJ8zUtluNJbd134/tJS7SsVQepj5Wz\n"
    "tCO7TG1F8PapspUwtP1MVYwnSlcUfIKdzXOS0xZKBgyMUNGPHgm+F6HmIcr9g+UQ\n"
    "vIOlCsRnKPZzFBQ9RnbDhxSJITRNrw9FDKZJobq7nMWxM4MphQIDAQABo4IBMDCC\n"
    "ASwwDwYDVR0TAQH/BAUwAwEB/zAdBgNVHQ4EFgQUTiJUIBiV5uNu5g/6+rkS7QYX\n"
    "jzkwHwYDVR0jBBgwFoAUA95QNVbRTLtm8KPiGxvDl7I90VUwDgYDVR0PAQH/BAQD\n"
    "AgGGMHQGCCsGAQUFBwEBBGgwZjAjBggrBgEFBQcwAYYXaHR0cDovL29jc3AuZGln\n"
    "aWNlcnQuY24wPwYIKwYBBQUHMAKGM2h0dHA6Ly9jYWNlcnRzLmRpZ2ljZXJ0LmNu\n"
    "L0RpZ2lDZXJ0R2xvYmFsUm9vdENBLmNydDBABgNVHR8EOTA3MDWgM6Axhi9odHRw\n"
    "Oi8vY3JsLmRpZ2ljZXJ0LmNuL0RpZ2lDZXJ0R2xvYmFsUm9vdENBLmNybDARBgNV\n"
    "HSAECjAIMAYGBFUdIAAwDQYJKoZIhvcNAQELBQADggEBAHRBl3jN7+XHBUK0dZnu\n"
    "hMdoNwD1nCROU3BTIh1TNzRI0bQ0m5+C/dCRzzlqoSAFHUlOi+OiDltWkXTzmQn6\n"
    "Z8bH5PFBy5sYpc/8cNPoSzhyqcpvvEZvv/Ivc0Up+dzma7vBDJC9WrMRUUlSFSQp\n"
    "kdXSmphDNkXJsgARmxzc18IN6LYMRiOWlY7RE2F900pPW60BvJHHNCX0bbSRj/Ql\n"
    "bmVq8wuftBD++D+RS8K++ujpMjFBROyWfBX+woQDGsMazkmgulQdnZrdj476elOL\n"
    "axRvrSgEorju1kJM7M65z2RUZrfzQYW/1rs8mRUXin6iEtad/Rv1ZI1WGYmWPyBm\n"
    "pbo=\n"
    "-----END CERTIFICATE-----\n";
at_http_rev_mqttc_info rev_mqttc_info = {0};
//生成注册内容body
static void creat_reg_body_user(http_info_t*p,char *mac,uint16_t dev_slave_id, char *dev_name, char *dev_type)
{
    if (p == T_NULL || mac == T_NULL  || dev_name == T_NULL || dev_type == T_NULL)
    {
        return;
    }
    cJSON *root = cJSON_CreateObject();
    cJSON_AddStringToObject(root, "mac", mac);
    cJSON_AddNumberToObject(root, "slaveId", dev_slave_id); // 设备ID
    cJSON_AddStringToObject(root, "deviceName", dev_name);
    cJSON_AddStringToObject(root, "type", dev_type);//设备type
    char *json_string = cJSON_PrintUnformatted(root);
    if (json_string != NULL)
    {
        strncpy(p->body, json_string, sizeof(p->body) - 1);
        p->body[sizeof(p->body) - 1] = '\0'; // 确保字符串以null结尾
        AT_FREE(json_string); // 释放cJSON生成的字符串
    }
    cJSON_Delete(root); // 删除cJSON对象
}
uint8_t ml307_register_callback(void *Ptx, uint8_t *dataBuf, uint8_t data_len,
                             uint8_t *cmd_Urc_String) {
    printf("ml307_register_callback handle OK  . %s\r\n", cmd_Urc_String);
    return 0;
}
//添加SSL根证书														 
static void ssl_flash(void){
	 ml307_error_t ret;
	 t_at_send_time_set(ML307R, 1200);//太快了模块会出问题
   char *tmpcmd = AT_MALLOC(2000);//创建发送域
   uint16_t tmpcmd_len = 2000;
   if(tmpcmd==T_NULL){ AT_FREE(tmpcmd);return;}
	 uint16_t len = 0;
	 AT_CMD_FORMAT_AUTO_CRLF(tmpcmd, tmpcmd_len, &len, "AT+MSSLCERTWR=\"t.cer\",0,%d",strlen(tcer)+2);//尾号2个多余的补上
   printf("cmd:\r\n%s\r\n", tmpcmd);
   ret=ml307_send_cmd(tmpcmd, len, ">", ml307_register_callback, 1000, 1);
	 
	 AT_CMD_FORMAT_AUTO_CRLF(tmpcmd, tmpcmd_len, &len, "%s",tcer);
   printf("cmd:\r\n%s\r\n", tmpcmd);
   ret=ml307_send_cmd(tmpcmd, len, "OK", ml307_register_callback, 1000, 1);
	 AT_FREE(tmpcmd);
	t_at_send_time_set(ML307R, 500);//太快了模块会出问题
	 return;
}													 

http_status_t at_http_register_init(char *mac,uint16_t productId)  // 初始化注册
{
	  ml307_error_t ret;
	  char *tmpcmd = AT_MALLOC(150);//创建发送域
    uint8_t tmpcmd_len = 150;
	  uint16_t len = 0;
	  if(tmpcmd==T_NULL){
			
			
			  AT_FREE(tmpcmd);
		    return HTTP_OK;
		
		}
		
    http_info.process_sta = 0; // 初始化状态为未开始注册
		
    creat_reg_body_user(&http_info,mac,1,"dev_aiaodido32","33333333444444445555555566666666");
    // 创建注册内容
    // 发送HTTP POST请求
    // 这里需要实现具体的HTTP请求发送逻辑
    // 假设发送成功并返回响应数据到rev_mqttc_info
    // 发送AT指令
		ssl_flash();
		AT_CMD_FORMAT_AUTO_CRLF(tmpcmd, tmpcmd_len, &len, "AT");
    printf("cmd:\r\n%s\r\n", tmpcmd);
    ret = ml307_send_cmd(tmpcmd, len, "OK", ml307_register_callback, 1000, 1);
		
		
    AT_CMD_FORMAT_AUTO_CRLF(tmpcmd, tmpcmd_len, &len, "AT+MHTTPDEL=%d",0);
    printf("cmd:\r\n%s\r\n", tmpcmd);
    ret = ml307_send_cmd(tmpcmd, len, "OK", ml307_register_callback, 1000, 1);

    AT_CMD_FORMAT_AUTO_CRLF(tmpcmd, tmpcmd_len, &len, "AT+MSSLCFG=\"auth\",%d,%d",0,1);
    printf("cmd:\r\n%s\r\n", tmpcmd);
    ret = ml307_send_cmd(tmpcmd, len, "OK", ml307_register_callback, 1000, 1);

    AT_CMD_FORMAT_AUTO_CRLF(tmpcmd, tmpcmd_len, &len, "AT+MSSLCFG=\"cert\",%d,\"t.cer\",\"\",\"\"",0);
    printf("cmd:\r\n%s\r\n", tmpcmd);
    ret = ml307_send_cmd(tmpcmd, len, "OK", ml307_register_callback, 1000, 1);

    AT_CMD_FORMAT_AUTO_CRLF(tmpcmd, tmpcmd_len, &len, "AT+MSSLCFG=\"version\",%d,%d",0,3);
    printf("cmd:\r\n%s\r\n", tmpcmd);
    ret = ml307_send_cmd(tmpcmd, len, "OK", ml307_register_callback, 1000, 1);

    AT_CMD_FORMAT_AUTO_CRLF(tmpcmd, tmpcmd_len, &len, "AT+MHTTPCREATE=\"%s\"", http_info.http_url);
    printf("cmd:\r\n%s\r\n", tmpcmd);
    ret = ml307_send_cmd(tmpcmd, len, "+MHTTPCREATE:", ml307_register_callback, 1000, 1);
		
    vTaskDelay(1000);
		
    AT_CMD_FORMAT_AUTO_CRLF(tmpcmd, tmpcmd_len, &len, "AT+MHTTPCFG=\"ssl\",%d,%d,%d",0,1,0);
    printf("cmd:\r\n%s\r\n", tmpcmd);
    ret = ml307_send_cmd(tmpcmd, len, "OK", ml307_register_callback, 1000, 1);
		if(ret==ml_send_fail){
		   printf("fiale ssl\r\n");
		}
		
    AT_CMD_FORMAT_AUTO_CRLF(tmpcmd, tmpcmd_len, &len, "AT+MHTTPCFG=\"chunked\",%d,%d",0,0);
    printf("cmd:\r\n%s\r\n", tmpcmd);
    ret = ml307_send_cmd(tmpcmd, len, "OK", ml307_register_callback, 1000, 1);

    AT_CMD_FORMAT_AUTO_CRLF(tmpcmd, tmpcmd_len, &len, "AT+MHTTPCFG=\"urlencode\",%d,%d",0,0);
    printf("cmd:\r\n%s\r\n", tmpcmd);
    ret = ml307_send_cmd(tmpcmd, len, "OK", ml307_register_callback, 1000, 1);

    AT_CMD_FORMAT_AUTO_CRLF(tmpcmd, tmpcmd_len, &len, "AT+MHTTPHEADER=%d,%d,%d,\"Content-Type: application/json\"",0,0,0);
    printf("cmd:\r\n%s\r\n", tmpcmd);
    ret = ml307_send_cmd(tmpcmd, len, "OK", ml307_register_callback, 1000, 1);

    AT_CMD_FORMAT_AUTO_CRLF(tmpcmd, tmpcmd_len, &len, "AT+MHTTPCONTENT=%d,%d,%d,\"%s\"",0,0,0,http_info.body);
    printf("cmd:\r\n%s\r\n", tmpcmd);
    ret = ml307_send_cmd(tmpcmd, len, "OK", ml307_register_callback, 1000, 1);

    AT_CMD_FORMAT_AUTO_CRLF(tmpcmd, tmpcmd_len, &len, "AT+MHTTPREQUEST=%d,%d,%d,\"%s\"",0,2,0,http_info.reg_url_path);
    printf("cmd:\r\n%s\r\n", tmpcmd);
    ret = ml307_send_cmd(tmpcmd, len, "OK", ml307_register_callback, 1000, 1);
    http_info.process_sta = 1; // 设置状态为注册过程
    //处理数据在URCcallback请参考URC部分文档
		AT_FREE(tmpcmd);
		t_at_send_time_set(ML307R, 100);//改回默认
//		while(1){//开启注册后需要自己
//		  vTaskDelay(1000);
//		}
		 vTaskDelay(8000);

    return HTTP_OK; // 返回成功状态
}
// 找到最外层的 JSON 边界

/**
 * @brief 查找字符串中最外层JSON对象的边界
 * @param input 输入字符串（可能包含非JSON内容）
 * @param start 输出参数，指向JSON起始位置（'{'）
 * @param end 输出参数，指向JSON结束位置（'}'）
 * @return 成功返回0，失败返回-1
 * 
 * @note 该函数仅查找最外层{}边界，不验证JSON内容有效性
 */
static int find_outer_json_boundaries(const char *input, const char **start, const char **end) 
{
    // 参数检查
    if (input == NULL || start == NULL || end == NULL) {
        return -1;
    }

    int brace_depth = 0;          // 大括号嵌套深度计数器
    const char *json_start = NULL; // 记录JSON起始位置
    const char *p = input;         // 遍历指针

    // 遍历字符串查找最外层{}
    while (*p != '\0') {
        if (*p == '{') {
            if (brace_depth == 0) {
                json_start = p;  // 记录最外层'{'位置
            }
            brace_depth++;       // 增加嵌套深度
        } 
        else if (*p == '}') {
            brace_depth--;       // 减少嵌套深度
            
            // 当回到最外层时记录结束位置
            if (brace_depth == 0 && json_start != NULL) {
                *start = json_start;
                *end = p;
                return 0;  // 成功找到边界
            }
            
            // 处理大括号不匹配的情况
            if (brace_depth < 0) {
                return -1;
            }
        }
        p++;
    }

    // 检查是否找到完整边界
    if (json_start == NULL || brace_depth != 0) {
        return -1;  // 未找到有效JSON边界
    }

    return -1;  // 正常情况下应该在循环内返回，这里作为保底
}

/**
 * @brief 查找并复制最外层的 JSON 内容
 * @param input  输入字符串（可能包含非 JSON 前缀/后缀）
 * @param output 输出缓冲区（用于存储提取的 JSON）
 * @param output_size 输出缓冲区大小
 * @return JSON 长度（不含 '\0'），失败返回 -1
 */
static int register_find_outer_json_boundaries(const char *input, char *output, size_t output_size) {
    if (input == NULL || output == NULL || output_size == 0) {
        return -1;
    }
    
    const char *json_start = NULL;
    const char *json_end = NULL;
    int ret = find_outer_json_boundaries(input, &json_start, &json_end);
    if (ret != 0) {
        return -1;  // 未找到有效JSON
    }
    
    size_t json_len = json_end - json_start + 1;
    
    // 检查输出缓冲区是否足够
    if (json_len + 1 > output_size) {
        return -1;  // 缓冲区不足
    }
    
    memmove(output, json_start, json_len);
    output[json_len] = '\0';  

    return (int)json_len;  
}
//返回的注册信息
#include "j_parm_a.h"
char ptsout[300];
uint8_t cb_mqtt_rev(void *Ptx, uint8_t *dataBuf, uint8_t len, uint8_t *cmd_UrcString) {
	  if(Ptx==NULL) return 0; // 返回错误码
	  printf("http=%s\r\n",dataBuf);
	  memset(ptsout,0,300);
    http_info.process_sta = 2; // 设置状态为URC过程
    register_find_outer_json_boundaries((const char*)dataBuf,ptsout,300);
    
    // 2. 解析JSON数据
    cJSON *root = cJSON_Parse((char*)ptsout);
    if (!root) {
        printf("JSON not find!\n");
        return 0; // 返回错误码
    }
    // 3. 获取结构体指针
    at_http_rev_mqttc_info *mqtt_info = (at_http_rev_mqttc_info *)Ptx;
    
    // 4. 提取data对象
    cJSON *data = cJSON_GetObjectItem(root, "data");
    if (!data) {
        printf("data not find!\n");
        cJSON_Delete(root);
        return 0;
    }
    // 5. 填充结构体字段
    cJSON *server = cJSON_GetObjectItem(data, "server");
    cJSON *clientId = cJSON_GetObjectItem(data, "clientId");
    cJSON *username = cJSON_GetObjectItem(data, "username");
    cJSON *password = cJSON_GetObjectItem(data, "password");
    cJSON *subTopic = cJSON_GetObjectItem(data, "subscribeTopic");
    cJSON *pubTopic = cJSON_GetObjectItem(data, "reportTopic");
    
    // 6. 检查字段是否存在并复制数据
    if (server) strncpy(mqtt_info->sever_addr, server->valuestring, sizeof(mqtt_info->sever_addr)-1);
    if (clientId) strncpy(mqtt_info->mqttc_clientId, clientId->valuestring, sizeof(mqtt_info->mqttc_clientId)-1);
    if (username) strncpy(mqtt_info->mqttc_userName, username->valuestring, sizeof(mqtt_info->mqttc_userName)-1);
    if (password) strncpy(mqtt_info->mqttc_passWord, password->valuestring, sizeof(mqtt_info->mqttc_passWord)-1);
    if (subTopic) strncpy(mqtt_info->mqttc_subTopic, subTopic->valuestring, sizeof(mqtt_info->mqttc_subTopic)-1);
    if (pubTopic) strncpy(mqtt_info->mqttc_pubTopic, pubTopic->valuestring, sizeof(mqtt_info->mqttc_pubTopic)-1);
    
    // 7. 释放JSON对象
    cJSON_Delete(root);
    http_info.process_sta = 4;      //设置状态为注册成功
    set_http_register_status(1);    //注册已成功
    
    if(http_info.app_lock==0){//应用
        at_http_register_set_mqttc_info(mqtt_info); // 设置MQTT客户端信息
        j_parm_set_parm_update_flag(j_parm, "ml_cfg");
        http_info.app_lock=1; 
    }
    return 1; // 返回成功
}

//注册应用将注册到的服务器地址应用到ML307R
void at_http_register_set_mqttc_info(at_http_rev_mqttc_info *mqtt_info) {
    if (mqtt_info == T_NULL) {
        return;
    }
    // 设置MQTT服务器地址
    ml307_set_mqttc_host(0, &ml307_cfg, mqtt_info->sever_addr);
    // 设置MQTT客户端ID
    ml307_set_mqttc_client_id(0, &ml307_cfg, mqtt_info->mqttc_clientId);
    // 设置MQTT用户名
    ml307_set_mqttc_user_name(0, &ml307_cfg, mqtt_info->mqttc_userName);
    // 设置MQTT密码
    ml307_set_mqttc_password(0, &ml307_cfg, mqtt_info->mqttc_passWord);
    // 设置MQTT订阅主题
    ml307_set_mqttc_subscribe_topic(0, &ml307_cfg, mqtt_info->mqttc_subTopic);
    // 设置MQTT发布主题
    ml307_set_mqttc_publish_topic(0, &ml307_cfg, mqtt_info->mqttc_pubTopic); 		
}
